home *** CD-ROM | disk | FTP | other *** search
/ QRZ! Ham Radio 8 / QRZ Ham Radio Callsign Database - Volume 8.iso / mac / files / t_sys5 / 92052tar.gz / 920528.tar / lapb.c < prev    next >
C/C++ Source or Header  |  1992-05-14  |  42KB  |  1,673 lines

  1. /* @(#) $Header: lapb.c,v 1.22 92/05/14 13:20:12 deyke Exp $ */
  2.  
  3. /* Link Access Procedures Balanced (LAPB), the upper sublayer of
  4.  * AX.25 Level 2.
  5.  */
  6. #include <time.h>
  7. #include "global.h"
  8. #include "mbuf.h"
  9. #include "timer.h"
  10. #include "ax25.h"
  11. #include "lapb.h"
  12. #include "netrom.h"
  13. #include "asy.h"
  14. #include "cmdparse.h"
  15. #include "netuser.h"
  16.  
  17. extern struct ax25_cb *netrom_server_axcb;
  18.  
  19. char  *ax25states[] = {
  20.   "Disconnected",
  21.   "Conn pending",
  22.   "Connected",
  23.   "Disc pending"
  24. };
  25.  
  26. char  *ax25reasons[] = {
  27.   "Normal",
  28.   "Reset",
  29.   "Timeout",
  30.   "Network"
  31. };
  32.  
  33. int  ax_maxframe =      7;      /* Transmit flow control level */
  34. int  ax_paclen   =    236;      /* Maximum outbound packet size */
  35. int  ax_pthresh  =     64;      /* Send polls for packets larger than this */
  36. int  ax_retry    =     10;      /* Retry limit */
  37. int32 ax_t1init  =   5000;      /* Retransmission timeout */
  38. int32 ax_t2init  =   2000;      /* Acknowledgement delay timeout */
  39. int32 ax_t3init  = 900000;      /* No-activity timeout */
  40. int32 ax_t4init  =  60000;      /* Busy timeout */
  41. int32 ax_t5init  =   1000;      /* Packet assembly timeout */
  42. int  ax_window   =   2048;      /* Local flow control limit */
  43. struct ax25_cb *axcb_server;    /* Server control block */
  44.  
  45. static struct ax25_cb *axcb_head;
  46.  
  47. static int is_flexnet __ARGS((char *call, int store));
  48. static void reset_t1 __ARGS((struct ax25_cb *cp));
  49. static void inc_t1 __ARGS((struct ax25_cb *cp));
  50. static void send_packet __ARGS((struct ax25_cb *cp, int type, int cmdrsp, struct mbuf *data));
  51. static int busy __ARGS((struct ax25_cb *cp));
  52. static void send_ack __ARGS((struct ax25_cb *cp, int cmdrsp));
  53. static void try_send __ARGS((struct ax25_cb *cp, int fill_sndq));
  54. static void setaxstate __ARGS((struct ax25_cb *cp, int newstate));
  55. static void t1_timeout __ARGS((struct ax25_cb *cp));
  56. static void t2_timeout __ARGS((struct ax25_cb *cp));
  57. static void t3_timeout __ARGS((struct ax25_cb *cp));
  58. static void t4_timeout __ARGS((struct ax25_cb *cp));
  59. static void t5_timeout __ARGS((struct ax25_cb *cp));
  60. static struct ax25_cb *create_axcb __ARGS((struct ax25_cb *prototype));
  61. static void build_path __ARGS((struct ax25_cb *cp, struct iface *ifp, struct ax25 *hdr, int reverse));
  62. static int put_reseq __ARGS((struct ax25_cb *cp, struct mbuf *bp, int ns));
  63. static int dodigipeat __ARGS((int argc, char *argv [], void *p));
  64. static int domaxframe __ARGS((int argc, char *argv [], void *p));
  65. static int domycall __ARGS((int argc, char *argv [], void *p));
  66. static int dopaclen __ARGS((int argc, char *argv [], void *p));
  67. static int dopthresh __ARGS((int argc, char *argv [], void *p));
  68. static int doaxreset __ARGS((int argc, char *argv [], void *p));
  69. static int doretry __ARGS((int argc, char *argv [], void *p));
  70. static int dorouteadd __ARGS((int argc, char *argv [], void *p));
  71. static void doroutelistentry __ARGS((struct ax_route *rp));
  72. static int doroutelist __ARGS((int argc, char *argv [], void *p));
  73. static int doroutestat __ARGS((int argc, char *argv [], void *p));
  74. static int doaxroute __ARGS((int argc, char *argv [], void *p));
  75. static int doaxstatus __ARGS((int argc, char *argv [], void *p));
  76. static int dot1 __ARGS((int argc, char *argv [], void *p));
  77. static int dot2 __ARGS((int argc, char *argv [], void *p));
  78. static int dot3 __ARGS((int argc, char *argv [], void *p));
  79. static int dot4 __ARGS((int argc, char *argv [], void *p));
  80. static int dot5 __ARGS((int argc, char *argv [], void *p));
  81. static int doaxwindow __ARGS((int argc, char *argv [], void *p));
  82.  
  83. /*---------------------------------------------------------------------------*/
  84.  
  85. static int is_flexnet(call, store)
  86. char *call;
  87. int store;
  88. {
  89.  
  90. #define FTABLESIZE 23
  91.  
  92.   struct ftable_t {
  93.     struct ftable_t *next;
  94.     char call[AXALEN];
  95.   };
  96.  
  97.   char *cp;
  98.   long hashval;
  99.   static struct ftable_t *ftable[FTABLESIZE];
  100.   struct ftable_t **tp;
  101.   struct ftable_t *p;
  102.  
  103.   cp = call;
  104.   hashval  = ((*cp++ << 23) & 0x0f000000);
  105.   hashval |= ((*cp++ << 19) & 0x00f00000);
  106.   hashval |= ((*cp++ << 15) & 0x000f0000);
  107.   hashval |= ((*cp++ << 11) & 0x0000f000);
  108.   hashval |= ((*cp++ <<  7) & 0x00000f00);
  109.   hashval |= ((*cp++ <<  3) & 0x000000f0);
  110.   hashval |= ((*cp   >>  1) & 0x0000000f);
  111.   tp = ftable + (hashval % FTABLESIZE);
  112.   for (p = *tp; p && !addreq(p->call, call); p = p->next) ;
  113.   if (!p && store) {
  114.     p = malloc(sizeof(*p));
  115.     addrcp(p->call, call);
  116.     p->next = *tp;
  117.     *tp = p;
  118.   }
  119.   return (int) (p != 0);
  120. }
  121.  
  122. /*---------------------------------------------------------------------------*/
  123.  
  124. static void reset_t1(cp)
  125. struct ax25_cb *cp;
  126. {
  127.   int32 tmp;
  128.  
  129.   tmp = cp->srtt + 4 * cp->mdev;
  130.   if (tmp < 500) tmp = 500;
  131.   set_timer(&cp->timer_t1, tmp);
  132. }
  133.  
  134. /*---------------------------------------------------------------------------*/
  135.  
  136. static void inc_t1(cp)
  137. struct ax25_cb *cp;
  138. {
  139.   int32 tmp;
  140.  
  141.   tmp = (dur_timer(&cp->timer_t1) * 5 + 2) / 4;
  142.   if (tmp > 10 * cp->srtt) tmp = 10 * cp->srtt;
  143.   if (tmp < 500) tmp = 500;
  144.   set_timer(&cp->timer_t1, tmp);
  145. }
  146.  
  147. /*---------------------------------------------------------------------------*/
  148.  
  149. #define next_seq(n)  (((n) + 1) & 7)
  150.  
  151. /*---------------------------------------------------------------------------*/
  152.  
  153. static void send_packet(cp, type, cmdrsp, data)
  154. struct ax25_cb *cp;
  155. int  type;
  156. int  cmdrsp;
  157. struct mbuf *data;
  158. {
  159.  
  160.   int  control;
  161.   struct mbuf *bp;
  162.  
  163.   if (cp->mode == STREAM && (type == I || type == UI)) {
  164.     if (!(bp = pushdown(data, 1))) {
  165.       free_p(data);
  166.       return;
  167.     }
  168.     *bp->data = PID_NO_L3;
  169.     data = bp;
  170.   }
  171.  
  172.   control = type;
  173.   if (type == I) {
  174.     control |= (cp->vs << 1);
  175.     cp->vs = next_seq(cp->vs);
  176.   }
  177.   if ((type & 3) != U) {
  178.     control |= (cp->vr << 5);
  179.     stop_timer(&cp->timer_t2);
  180.   }
  181.   if (cmdrsp & PF) control |= PF;
  182.   if (!(bp = pushdown(data, 1))) {
  183.     free_p(data);
  184.     return;
  185.   }
  186.   *bp->data = control;
  187.   data = bp;
  188.  
  189.   if (cmdrsp & DST_C)
  190.     cp->hdr.cmdrsp = LAPB_COMMAND;
  191.   else if (cmdrsp & SRC_C)
  192.     cp->hdr.cmdrsp = LAPB_RESPONSE;
  193.   else
  194.     cp->hdr.cmdrsp = VERS1;
  195.   if (!(bp = htonax25(&cp->hdr, data))) {
  196.     free_p(data);
  197.     return;
  198.   }
  199.   data = bp;
  200.  
  201.   if (type == RR || type == REJ || type == UA) cp->rnrsent = 0;
  202.   if (type == RNR) cp->rnrsent = 1;
  203.   if (type == REJ) cp->rejsent = 1;
  204.   if (cmdrsp == POLL) cp->polling = 1;
  205.   if (type == I || cmdrsp == POLL) start_timer(&cp->timer_t1);
  206.  
  207.   axroute(cp, data);
  208. }
  209.  
  210. /*---------------------------------------------------------------------------*/
  211.  
  212. static int  busy(cp)
  213. struct ax25_cb *cp;
  214. {
  215.   return cp->peer ? space_ax(cp->peer) <= 0 : cp->rcvcnt >= ax_window;
  216. }
  217.  
  218. /*---------------------------------------------------------------------------*/
  219.  
  220. static void send_ack(cp, cmdrsp)
  221. struct ax25_cb *cp;
  222. int  cmdrsp;
  223. {
  224.   if (busy(cp))
  225.     send_packet(cp, RNR, cmdrsp, NULLBUF);
  226.   else if (!cp->rejsent && (cp->reseq[0].bp || cp->reseq[1].bp ||
  227.                 cp->reseq[2].bp || cp->reseq[3].bp ||
  228.                 cp->reseq[4].bp || cp->reseq[5].bp ||
  229.                 cp->reseq[6].bp || cp->reseq[7].bp))
  230.     send_packet(cp, REJ, cmdrsp, NULLBUF);
  231.   else
  232.     send_packet(cp, RR, cmdrsp, NULLBUF);
  233. }
  234.  
  235. /*---------------------------------------------------------------------------*/
  236.  
  237. static void try_send(cp, fill_sndq)
  238. struct ax25_cb *cp;
  239. int  fill_sndq;
  240. {
  241.  
  242.   int  cnt;
  243.   struct mbuf *bp;
  244.  
  245.   stop_timer(&cp->timer_t5);
  246.   while (cp->unack < cp->cwind) {
  247.     if (cp->state != CONNECTED || cp->remote_busy) return;
  248.     if (fill_sndq && cp->t_upcall) {
  249.       cnt = space_ax(cp);
  250.       if (cnt > 0) {
  251.     (*cp->t_upcall)(cp, cnt);
  252.     if (cp->unack >= cp->cwind) return;
  253.       }
  254.     }
  255.     if (!cp->sndq) return;
  256.     if (cp->mode == STREAM) {
  257.       cnt = len_p(cp->sndq);
  258.       if (cnt < ax_paclen) {
  259.     if (cp->unack) return;
  260.     if (!cp->peer && cp->sndqtime + ax_t5init - msclock() > 0) {
  261.       set_timer(&cp->timer_t5, cp->sndqtime + ax_t5init - msclock());
  262.       start_timer(&cp->timer_t5);
  263.       return;
  264.     }
  265.       }
  266.       if (cnt > ax_paclen) cnt = ax_paclen;
  267.       if (!(bp = alloc_mbuf(cnt))) return;
  268.       pullup(&cp->sndq, bp->data, bp->cnt = cnt);
  269.     } else {
  270.       bp = dequeue(&cp->sndq);
  271.     }
  272.     enqueue(&cp->resndq, bp);
  273.     cp->unack++;
  274.     cp->sndtime[cp->vs] = msclock();
  275.     dup_p(&bp, bp, 0, MAXINT16);
  276.     send_packet(cp, I, CMD, bp);
  277.   }
  278. }
  279.  
  280. /*---------------------------------------------------------------------------*/
  281.  
  282. static void setaxstate(cp, newstate)
  283. struct ax25_cb *cp;
  284. int  newstate;
  285. {
  286.   int  oldstate;
  287.  
  288.   oldstate = cp->state;
  289.   cp->state = newstate;
  290.   cp->polling = 0;
  291.   cp->retry = 0;
  292.   stop_timer(&cp->timer_t1);
  293.   stop_timer(&cp->timer_t2);
  294.   stop_timer(&cp->timer_t4);
  295.   stop_timer(&cp->timer_t5);
  296.   reset_t1(cp);
  297.   switch (newstate) {
  298.   case DISCONNECTED:
  299.     if (cp->peer) close_ax(cp->peer);
  300.     if (cp->s_upcall) (*cp->s_upcall)(cp, oldstate, newstate);
  301.     if (cp->peer && cp->peer->state == DISCONNECTED) {
  302.       del_ax(cp->peer);
  303.       del_ax(cp);
  304.     }
  305.     break;
  306.   case CONNECTING:
  307.     if (cp->s_upcall) (*cp->s_upcall)(cp, oldstate, newstate);
  308.     send_packet(cp, SABM, POLL, NULLBUF);
  309.     break;
  310.   case CONNECTED:
  311.     if (cp->peer && cp->peer->state == DISCONNECTED) {
  312.       send_packet(cp->peer, UA, FINAL, NULLBUF);
  313.       setaxstate(cp->peer, CONNECTED);
  314.     }
  315.     if (cp->s_upcall) (*cp->s_upcall)(cp, oldstate, newstate);
  316.     try_send(cp, 1);
  317.     break;
  318.   case DISCONNECTING:
  319.     if (cp->peer) close_ax(cp->peer);
  320.     if (cp->s_upcall) (*cp->s_upcall)(cp, oldstate, newstate);
  321.     send_packet(cp, DISC, POLL, NULLBUF);
  322.     break;
  323.   }
  324. }
  325.  
  326. /*---------------------------------------------------------------------------*/
  327.  
  328. static void t1_timeout(cp)
  329. struct ax25_cb *cp;
  330. {
  331.   inc_t1(cp);
  332.   cp->cwind = 1;
  333.   if (++cp->retry > ax_retry) cp->reason = TIMEOUT;
  334.   switch (cp->state) {
  335.   case DISCONNECTED:
  336.     break;
  337.   case CONNECTING:
  338.     if (cp->peer && cp->peer->state == DISCONNECTED)
  339.       if (cp->retry > 2)
  340.     setaxstate(cp, DISCONNECTED);
  341.       else
  342.     start_timer(&cp->timer_t1);
  343.     else if (cp->retry > ax_retry)
  344.       setaxstate(cp, DISCONNECTED);
  345.     else
  346.       send_packet(cp, SABM, POLL, NULLBUF);
  347.     break;
  348.   case CONNECTED:
  349.     if (cp->retry > ax_retry) {
  350.       setaxstate(cp, DISCONNECTING);
  351.     } else if (!cp->polling && !cp->remote_busy && cp->unack &&
  352.            len_p(cp->resndq) <= ax_pthresh) {
  353.       int  old_vs;
  354.       struct mbuf *bp;
  355.       old_vs = cp->vs;
  356.       cp->vs = (cp->vs - cp->unack) & 7;
  357.       cp->sndtime[cp->vs] = 0;
  358.       dup_p(&bp, cp->resndq, 0, MAXINT16);
  359.       send_packet(cp, I, POLL, bp);
  360.       cp->vs = old_vs;
  361.     } else {
  362.       send_ack(cp, POLL);
  363.     }
  364.     break;
  365.   case DISCONNECTING:
  366.     if (cp->retry > ax_retry)
  367.       setaxstate(cp, DISCONNECTED);
  368.     else
  369.       send_packet(cp, DISC, POLL, NULLBUF);
  370.     break;
  371.   }
  372. }
  373.  
  374. /*---------------------------------------------------------------------------*/
  375.  
  376. static void t2_timeout(cp)
  377. struct ax25_cb *cp;
  378. {
  379.   send_ack(cp, RESP);
  380. }
  381.  
  382. /*---------------------------------------------------------------------------*/
  383.  
  384. static void t3_timeout(cp)
  385. struct ax25_cb *cp;
  386. {
  387.   if (!run_timer(&cp->timer_t1)) send_ack(cp, POLL);
  388. }
  389.  
  390. /*---------------------------------------------------------------------------*/
  391.  
  392. static void t4_timeout(cp)
  393. struct ax25_cb *cp;
  394. {
  395.   if (!cp->polling) send_ack(cp, POLL);
  396. }
  397.  
  398. /*---------------------------------------------------------------------------*/
  399.  
  400. static void t5_timeout(cp)
  401. struct ax25_cb *cp;
  402. {
  403.   try_send(cp, 1);
  404. }
  405.  
  406. /*---------------------------------------------------------------------------*/
  407.  
  408. static struct ax25_cb *create_axcb(prototype)
  409. struct ax25_cb *prototype;
  410. {
  411.   struct ax25_cb *cp;
  412.  
  413.   if (prototype) {
  414.     cp = (struct ax25_cb *) malloc(sizeof(struct ax25_cb ));
  415.     *cp = *prototype;
  416.   } else
  417.     cp = (struct ax25_cb *) calloc(1, sizeof(struct ax25_cb ));
  418.   cp->cwind = 1;
  419.   cp->timer_t1.func = (void (*)()) t1_timeout;
  420.   cp->timer_t1.arg = cp;
  421.   cp->timer_t2.func = (void (*)()) t2_timeout;
  422.   cp->timer_t2.arg = cp;
  423.   cp->timer_t3.func = (void (*)()) t3_timeout;
  424.   cp->timer_t3.arg = cp;
  425.   cp->timer_t4.func = (void (*)()) t4_timeout;
  426.   cp->timer_t4.arg = cp;
  427.   cp->timer_t5.func = (void (*)()) t5_timeout;
  428.   cp->timer_t5.arg = cp;
  429.   cp->next = axcb_head;
  430.   return axcb_head = cp;
  431. }
  432.  
  433. /*---------------------------------------------------------------------------*/
  434.  
  435. static void build_path(cp, ifp, hdr, reverse)
  436. struct ax25_cb *cp;
  437. struct iface *ifp;
  438. struct ax25 *hdr;
  439. int  reverse;
  440. {
  441.  
  442.   char  *dest;
  443.   int  d;
  444.   int  i;
  445.   struct ax_route *rp;
  446.  
  447.   if (reverse) {
  448.  
  449.     /*** copy hdr into control block ***/
  450.  
  451.     addrcp(cp->hdr.dest, hdr->source);
  452.     addrcp(cp->hdr.source, hdr->dest);
  453.     for (i = 0; i < hdr->ndigis; i++)
  454.       addrcp(cp->hdr.digis[i], hdr->digis[hdr->ndigis-1-i]);
  455.     cp->hdr.ndigis = hdr->ndigis;
  456.  
  457.     /*** find my last address ***/
  458.  
  459.     cp->hdr.nextdigi = 0;
  460.     for (i = 0; i < cp->hdr.ndigis; i++)
  461.       if (ismyax25addr(cp->hdr.digis[i])) cp->hdr.nextdigi = i + 1;
  462.  
  463.     cp->ifp = ifp;
  464.  
  465.   } else {
  466.  
  467.     /*** copy hdr into control block ***/
  468.  
  469.     cp->hdr = *hdr;
  470.  
  471.     /*** find my last address ***/
  472.  
  473.     cp->hdr.nextdigi = 0;
  474.     for (i = 0; i < cp->hdr.ndigis; i++)
  475.       if (ismyax25addr(cp->hdr.digis[i])) cp->hdr.nextdigi = i + 1;
  476.  
  477.     /*** remove all digipeaters before me ***/
  478.  
  479.     d = cp->hdr.nextdigi - 1;
  480.     if (d > 0) {
  481.       for (i = d; i < cp->hdr.ndigis; i++)
  482.     addrcp(cp->hdr.digis[i-d], cp->hdr.digis[i]);
  483.       cp->hdr.ndigis -= d;
  484.       cp->hdr.nextdigi = 1;
  485.     }
  486.  
  487.     /*** add necessary digipeaters and find interface ***/
  488.  
  489.     dest = cp->hdr.nextdigi < cp->hdr.ndigis ? cp->hdr.digis[cp->hdr.nextdigi] : cp->hdr.dest;
  490.     for (rp = ax_routeptr(dest, 0); rp; rp = rp->digi) {
  491.       if (rp->digi && cp->hdr.ndigis < MAXDIGIS) {
  492.     for (i = cp->hdr.ndigis - 1; i >= cp->hdr.nextdigi; i--)
  493.       addrcp(cp->hdr.digis[i+1], cp->hdr.digis[i]);
  494.     cp->hdr.ndigis++;
  495.     addrcp(cp->hdr.digis[cp->hdr.nextdigi], rp->digi->call);
  496.       }
  497.       cp->ifp = rp->ifp;
  498.     }
  499.     if (!cp->ifp) cp->ifp = axroute_default_ifp;
  500.  
  501.     /*** replace my address with hwaddr of interface ***/
  502.  
  503.     addrcp(cp->hdr.nextdigi ? cp->hdr.digis[0] : cp->hdr.source,
  504.        cp->ifp ? cp->ifp->hwaddr : Mycall);
  505.  
  506.   }
  507.  
  508.   cp->srtt = (ax_t1init * (1 + 2 * (cp->hdr.ndigis - cp->hdr.nextdigi))) / 2;
  509.   cp->mdev = cp->srtt / 4;
  510.   reset_t1(cp);
  511. }
  512.  
  513. /*---------------------------------------------------------------------------*/
  514.  
  515. static int  put_reseq(cp, bp, ns)
  516. struct ax25_cb *cp;
  517. struct mbuf *bp;
  518. int  ns;
  519. {
  520.  
  521.   char  *p;
  522.   int  cnt, sum;
  523.   struct axreseq *rp;
  524.   struct mbuf *tp;
  525.  
  526.   if (next_seq(ns) == cp->vr) return 0;
  527.   rp = &cp->reseq[ns];
  528.   if (rp->bp) return 0;
  529.   for (sum = 0, tp = bp; tp; tp = tp->next) {
  530.     cnt = tp->cnt;
  531.     p = tp->data;
  532.     while (cnt--) sum += uchar(*p++);
  533.   }
  534.   if (ns != cp->vr && sum == rp->sum) return 0;
  535.   rp->bp = bp;
  536.   rp->sum = sum;
  537.   return 1;
  538. }
  539.  
  540. /*---------------------------------------------------------------------------*/
  541.  
  542. int  lapb_input(iface, hdr, bp)
  543. struct iface *iface;
  544. struct ax25 *hdr;
  545. struct mbuf *bp;
  546. {
  547.  
  548.   int  cmdrsp;
  549.   int  control;
  550.   int  for_me;
  551.   int  nr;
  552.   int  ns;
  553.   int  pid;
  554.   int  type;
  555.   struct ax25_cb *cp;
  556.   struct ax25_cb *cpp;
  557.  
  558.   if (!bp) return (-1);
  559.   control = uchar(*bp->data);
  560.   type = ftype(control);
  561.   for_me = (ismyax25addr(hdr->dest) != NULLIF);
  562.  
  563.   if (!for_me &&
  564.       (type == UI ||
  565.        addreq(hdr->source, hdr->dest) ||
  566.        is_flexnet(hdr->source, 0) && is_flexnet(hdr->dest, 0))) {
  567.     struct mbuf *hbp;
  568.     if (!(hbp = htonax25(hdr, bp))) {
  569.       free_p(bp);
  570.       return (-1);
  571.     }
  572.     axroute(NULLAXCB, hbp);
  573.     return 0;
  574.   }
  575.  
  576.   (void) PULLCHAR(&bp);
  577.   if (bp) {
  578.     pid = uchar(*bp->data);
  579.     if (pid == PID_FLEXNET) is_flexnet(hdr->source, 1);
  580.   }
  581.  
  582.   switch (hdr->cmdrsp) {
  583.   case LAPB_COMMAND:
  584.     cmdrsp = DST_C | (control & PF);
  585.     break;
  586.   case LAPB_RESPONSE:
  587.     cmdrsp = SRC_C | (control & PF);
  588.     break;
  589.   default:
  590.     cmdrsp = VERS1;
  591.     break;
  592.   }
  593.  
  594.   for (cp = axcb_head; cp; cp = cp->next)
  595.     if (addreq(hdr->source, cp->hdr.dest) && addreq(hdr->dest, cp->hdr.source)) break;
  596.   if (!cp) {
  597.     if (for_me && netrom_server_axcb && isnetrom(hdr->source))
  598.       cp = create_axcb(netrom_server_axcb);
  599.     else if (for_me && axcb_server)
  600.       cp = create_axcb(axcb_server);
  601.     else
  602.       cp = create_axcb(NULLAXCB);
  603.     build_path(cp, iface, hdr, 1);
  604.     if (!for_me) {
  605.       cp->peer = cpp = create_axcb(NULLAXCB);
  606.       cpp->peer = cp;
  607.       build_path(cpp, NULLIF, hdr, 0);
  608.     } else
  609.       cpp = NULLAXCB;
  610.   } else
  611.     cpp = cp->peer;
  612.  
  613.   if (type == SABM) {
  614.     int  i;
  615.     build_path(cp, iface, hdr, 1);
  616.     if (cp->unack)
  617.       start_timer(&cp->timer_t1);
  618.     else
  619.       stop_timer(&cp->timer_t1);
  620.     stop_timer(&cp->timer_t2);
  621.     stop_timer(&cp->timer_t4);
  622.     cp->polling = 0;
  623.     cp->rnrsent = 0;
  624.     cp->rejsent = 0;
  625.     cp->remote_busy = 0;
  626.     cp->vr = 0;
  627.     cp->vs = cp->unack;
  628.     cp->retry = 0;
  629.     for (i = 0; i < 8; i++)
  630.       if (cp->reseq[i].bp) {
  631.     free_p(cp->reseq[i].bp);
  632.     cp->reseq[i].bp = 0;
  633.       }
  634.   }
  635.  
  636.   if (cp->mode == STREAM && type == I && pid != PID_NO_L3) {
  637.     cp->mode = DGRAM;
  638.     if (cpp) cpp->mode = DGRAM;
  639.   }
  640.  
  641.   set_timer(&cp->timer_t3, ax_t3init);
  642.   start_timer(&cp->timer_t3);
  643.  
  644.   switch (cp->state) {
  645.  
  646.   case DISCONNECTED:
  647.     if (for_me) {
  648.       if (type == SABM && cmdrsp != VERS1 && cp->r_upcall) {
  649.     send_packet(cp, UA, (cmdrsp == POLL) ? FINAL : RESP, NULLBUF);
  650.     setaxstate(cp, CONNECTED);
  651.       } else {
  652.     if (cmdrsp != RESP && cmdrsp != FINAL)
  653.       send_packet(cp, DM, (cmdrsp == POLL) ? FINAL : RESP, NULLBUF);
  654.     del_ax(cp);
  655.       }
  656.     } else {
  657.       if (type == SABM && cmdrsp != VERS1 && cpp->state == DISCONNECTED) {
  658.     setaxstate(cpp, CONNECTING);
  659.       } else if (type == SABM && cmdrsp != VERS1 && cpp->state == CONNECTING) {
  660.     build_path(cpp, NULLIF, hdr, 0);
  661.     send_packet(cpp, SABM, POLL, NULLBUF);
  662.       } else {
  663.     if (cmdrsp != RESP && cmdrsp != FINAL)
  664.       send_packet(cp, DM, (cmdrsp == POLL) ? FINAL : RESP, NULLBUF);
  665.     if (cpp->state == DISCONNECTED) {
  666.       del_ax(cpp);
  667.       del_ax(cp);
  668.     }
  669.       }
  670.     }
  671.     break;
  672.  
  673.   case CONNECTING:
  674.     switch (type) {
  675.     case I:
  676.     case RR:
  677.     case RNR:
  678.     case REJ:
  679.       break;
  680.     case SABM:
  681.       if (cmdrsp != VERS1) {
  682.     send_packet(cp, UA, (cmdrsp == POLL) ? FINAL : RESP, NULLBUF);
  683.     setaxstate(cp, CONNECTED);
  684.       }
  685.       break;
  686.     case UA:
  687.       if (cmdrsp != VERS1) {
  688.     setaxstate(cp, CONNECTED);
  689.       } else {
  690.     if (cpp && cpp->state == DISCONNECTED)
  691.       send_packet(cpp, DM, FINAL, NULLBUF);
  692.     cp->reason = RESET;
  693.     setaxstate(cp, DISCONNECTING);
  694.       }
  695.       break;
  696.     case DISC:
  697.       send_packet(cp, DM, (cmdrsp == POLL) ? FINAL : RESP, NULLBUF);
  698.     case DM:
  699.     case FRMR:
  700.       if (cpp && cpp->state == DISCONNECTED)
  701.     send_packet(cpp, DM, FINAL, NULLBUF);
  702.       cp->reason = RESET;
  703.       setaxstate(cp, DISCONNECTED);
  704.       break;
  705.     }
  706.     break;
  707.  
  708.   case CONNECTED:
  709.     switch (type) {
  710.     case I:
  711.     case RR:
  712.     case RNR:
  713.     case REJ:
  714.       stop_timer(&cp->timer_t1);
  715.       nr = control >> 5;
  716.       if (((cp->vs - nr) & 7) < cp->unack) {
  717.     if (!cp->polling) {
  718.       cp->retry = 0;
  719.       if (cp->sndtime[(nr-1)&7]) {
  720.         int32 rtt = msclock() - cp->sndtime[(nr-1)&7];
  721.         int32 abserr = (rtt > cp->srtt) ? rtt - cp->srtt : cp->srtt - rtt;
  722.         cp->srtt = ((AGAIN - 1) * cp->srtt + rtt + (AGAIN / 2)) / AGAIN;
  723.         cp->mdev = ((DGAIN - 1) * cp->mdev + abserr + (DGAIN / 2)) / DGAIN;
  724.         reset_t1(cp);
  725.         if (cp->cwind < ax_maxframe) {
  726.           cp->mdev += ((cp->srtt / cp->cwind + 2) / 4);
  727.           cp->cwind++;
  728.         }
  729.       }
  730.     }
  731.     while (((cp->vs - nr) & 7) < cp->unack) {
  732.       cp->resndq = free_p(cp->resndq);
  733.       cp->unack--;
  734.     }
  735.     if (cpp && cpp->rnrsent && !busy(cpp)) send_ack(cpp, RESP);
  736.       }
  737.       if (type == I) {
  738.     if (for_me &&
  739.         pid == PID_NETROM &&
  740.         cp->r_upcall != netrom_server_axcb->r_upcall) {
  741.       new_neighbor(hdr->source);
  742.       setaxstate(cp, DISCONNECTING);
  743.       free_p(bp);
  744.       return 0;
  745.     }
  746.     ns = (control >> 1) & 7;
  747.     if (!bp) bp = alloc_mbuf(0);
  748.     if (put_reseq(cp, bp, ns))
  749.       while (bp = cp->reseq[cp->vr].bp) {
  750.         cp->reseq[cp->vr].bp = 0;
  751.         cp->vr = next_seq(cp->vr);
  752.         cp->rejsent = 0;
  753.         if (cp->mode == STREAM) (void) PULLCHAR(&bp);
  754.         if (for_me) {
  755.           cp->rcvcnt += len_p(bp);
  756.           if (cp->mode == STREAM)
  757.         append(&cp->rcvq, bp);
  758.           else
  759.         enqueue(&cp->rcvq, bp);
  760.         } else
  761.           send_ax(cpp, bp);
  762.       }
  763.     if (cmdrsp == POLL)
  764.       send_ack(cp, FINAL);
  765.     else {
  766.       set_timer(&cp->timer_t2, ax_t2init);
  767.       start_timer(&cp->timer_t2);
  768.     }
  769.     if (cp->r_upcall && cp->rcvcnt) (*cp->r_upcall)(cp, cp->rcvcnt);
  770.       } else {
  771.     if (cmdrsp == POLL) send_ack(cp, FINAL);
  772.     if (cp->polling && cmdrsp == FINAL) cp->retry = cp->polling = 0;
  773.     if (type == RNR) {
  774.       if (!cp->remote_busy) cp->remote_busy = msclock();
  775.       set_timer(&cp->timer_t4, ax_t4init);
  776.       start_timer(&cp->timer_t4);
  777.       cp->cwind = 1;
  778.     } else {
  779.       cp->remote_busy = 0;
  780.       stop_timer(&cp->timer_t4);
  781.       if (cp->unack && type == REJ) {
  782.         int  old_vs;
  783.         struct mbuf *bp1;
  784.         old_vs = cp->vs;
  785.         cp->vs = (cp->vs - cp->unack) & 7;
  786.         cp->sndtime[cp->vs] = 0;
  787.         dup_p(&bp1, cp->resndq, 0, MAXINT16);
  788.         send_packet(cp, I, CMD, bp1);
  789.         cp->vs = old_vs;
  790.         cp->cwind = 1;
  791.       } else if (cp->unack && cmdrsp == FINAL) {
  792.         struct mbuf *bp1, *qp;
  793.         cp->vs = (cp->vs - cp->unack) & 7;
  794.         for (qp = cp->resndq; qp; qp = qp->anext) {
  795.           cp->sndtime[cp->vs] = 0;
  796.           dup_p(&bp1, qp, 0, MAXINT16);
  797.           send_packet(cp, I, CMD, bp1);
  798.         }
  799.       }
  800.     }
  801.       }
  802.       try_send(cp, 1);
  803.       if (cp->polling || cp->unack && !cp->remote_busy)
  804.     start_timer(&cp->timer_t1);
  805.       if (cp->closed && !cp->sndq && !cp->unack ||
  806.       cp->remote_busy && msclock() - cp->remote_busy > 900000L)
  807.     setaxstate(cp, DISCONNECTING);
  808.       break;
  809.     case SABM:
  810.       send_packet(cp, UA, (cmdrsp == POLL) ? FINAL : RESP, NULLBUF);
  811.       try_send(cp, 1);
  812.       break;
  813.     case DISC:
  814.       send_packet(cp, DM, (cmdrsp == POLL) ? FINAL : RESP, NULLBUF);
  815.     case DM:
  816.       setaxstate(cp, DISCONNECTED);
  817.       break;
  818.     case UA:
  819.       cp->remote_busy = 0;
  820.       stop_timer(&cp->timer_t4);
  821.       if (cp->unack) start_timer(&cp->timer_t1);
  822.       try_send(cp, 1);
  823.       break;
  824.     case FRMR:
  825.       setaxstate(cp, DISCONNECTING);
  826.       break;
  827.     }
  828.     break;
  829.  
  830.   case DISCONNECTING:
  831.     switch (type) {
  832.     case I:
  833.     case RR:
  834.     case RNR:
  835.     case REJ:
  836.     case SABM:
  837.       if (cmdrsp != RESP && cmdrsp != FINAL)
  838.     send_packet(cp, DM, (cmdrsp == POLL) ? FINAL : RESP, NULLBUF);
  839.       break;
  840.     case DISC:
  841.       send_packet(cp, DM, (cmdrsp == POLL) ? FINAL : RESP, NULLBUF);
  842.     case DM:
  843.     case UA:
  844.     case FRMR:
  845.       setaxstate(cp, DISCONNECTED);
  846.       break;
  847.     }
  848.     break;
  849.   }
  850.  
  851.   free_p(bp);
  852.   return 0;
  853. }
  854.  
  855. /*---------------------------------------------------------------------------*/
  856. /******************************* AX25 Commands *******************************/
  857. /*---------------------------------------------------------------------------*/
  858.  
  859. /* Control AX.25 digipeating */
  860.  
  861. static int  dodigipeat(argc, argv, p)
  862. int  argc;
  863. char  *argv[];
  864. void *p;
  865. {
  866.   return setintrc(&Digipeat, "Digipeat", argc, argv, 0, 2);
  867. }
  868.  
  869. /*---------------------------------------------------------------------------*/
  870.  
  871. /* Force a retransmission */
  872.  
  873. static int  doaxkick(argc, argv, p)
  874. int  argc;
  875. char  *argv[];
  876. void *p;
  877. {
  878.   struct ax25_cb *axp;
  879.  
  880.   axp = (struct ax25_cb *) ltop(htol(argv[1]));
  881.   if (!valid_ax(axp)) {
  882.     printf(Notval);
  883.     return 1;
  884.   }
  885.   kick_ax(axp);
  886.   return 0;
  887. }
  888.  
  889. /*---------------------------------------------------------------------------*/
  890.  
  891. /* Set maximum number of frames that will be allowed in flight */
  892.  
  893. static int  domaxframe(argc, argv, p)
  894. int  argc;
  895. char  *argv[];
  896. void *p;
  897. {
  898.   return setintrc(&ax_maxframe, "Maxframe", argc, argv, 1, 7);
  899. }
  900.  
  901. /*---------------------------------------------------------------------------*/
  902.  
  903. /* Display or change our AX.25 address */
  904.  
  905. static int  domycall(argc, argv, p)
  906. int  argc;
  907. char  *argv[];
  908. void *p;
  909. {
  910.   char  buf[15];
  911.  
  912.   if (argc < 2) {
  913.     pax25(buf, Mycall);
  914.     printf("Mycall %s\n", buf);
  915.   } else {
  916.     if (setcall(Mycall, argv[1]) == -1) return 1;
  917.     Mycall[ALEN] |= E;
  918.   }
  919.   return 0;
  920. }
  921.  
  922. /*---------------------------------------------------------------------------*/
  923.  
  924. /* Set maximum length of I-frame data field */
  925.  
  926. static int  dopaclen(argc, argv, p)
  927. int  argc;
  928. char  *argv[];
  929. void *p;
  930. {
  931.   return setintrc(&ax_paclen, "Paclen", argc, argv, 1, MAXINT16);
  932. }
  933.  
  934. /*---------------------------------------------------------------------------*/
  935.  
  936. /* Set size of I-frame above which polls will be sent after a timeout */
  937.  
  938. static int  dopthresh(argc, argv, p)
  939. int  argc;
  940. char  *argv[];
  941. void *p;
  942. {
  943.   return setintrc(&ax_pthresh, "Pthresh", argc, argv, 0, MAXINT16);
  944. }
  945.  
  946. /*---------------------------------------------------------------------------*/
  947.  
  948. /* Eliminate a AX25 connection */
  949.  
  950. static int  doaxreset(argc, argv, p)
  951. int  argc;
  952. char  *argv[];
  953. void *p;
  954. {
  955.   struct ax25_cb *cp;
  956.  
  957.   cp = (struct ax25_cb *) htol(argv[1]);
  958.   if (!valid_ax(cp)) {
  959.     printf(Notval);
  960.     return 1;
  961.   }
  962.   reset_ax(cp);
  963.   return 0;
  964. }
  965.  
  966. /*---------------------------------------------------------------------------*/
  967.  
  968. /* Set retry limit count */
  969.  
  970. static int  doretry(argc, argv, p)
  971. int  argc;
  972. char  *argv[];
  973. void *p;
  974. {
  975.   return setintrc(&ax_retry, "Retry", argc, argv, 0, MAXINT16);
  976. }
  977.  
  978. /*---------------------------------------------------------------------------*/
  979.  
  980. static int  dorouteadd(argc, argv, p)
  981. int  argc;
  982. char  *argv[];
  983. void *p;
  984. {
  985.  
  986.   char  tmp[AXALEN];
  987.   int  i, j, perm;
  988.   struct ax25 hdr;
  989.   struct iface *iface;
  990.  
  991.   argc--;
  992.   argv++;
  993.  
  994.   if (perm = !strcmp(*argv, "permanent")) {
  995.     argc--;
  996.     argv++;
  997.   }
  998.  
  999.   if (!(iface = if_lookup(*argv))) {
  1000.     printf("Interface \"%s\" unknown\n", *argv);
  1001.     return 1;
  1002.   }
  1003.   if (iface->output != ax_output) {
  1004.     printf("Interface \"%s\" not kiss\n", *argv);
  1005.     return 1;
  1006.   }
  1007.   argc--;
  1008.   argv++;
  1009.  
  1010.   if (argc <= 0) {
  1011.     printf("Usage: ax25 route add [permanent] <interface> default|<path>\n");
  1012.     return 1;
  1013.   }
  1014.  
  1015.   if (!strcmp(*argv, "default")) {
  1016.     axroute_default_ifp = iface;
  1017.     return 0;
  1018.   }
  1019.  
  1020.   if (setcall(hdr.source, *argv)) {
  1021.     printf("Invalid call \"%s\"\n", *argv);
  1022.     return 1;
  1023.   }
  1024.   argc--;
  1025.   argv++;
  1026.  
  1027.   for (hdr.nextdigi = 0; argc > 0; argc--, argv++)
  1028.     if (strncmp("via", *argv, strlen(*argv))) {
  1029.       if (hdr.nextdigi >= MAXDIGIS) {
  1030.     printf("Too many digipeaters (max %d)\n", MAXDIGIS);
  1031.     return 1;
  1032.       }
  1033.       if (setcall(hdr.digis[hdr.nextdigi++], *argv)) {
  1034.     printf("Invalid call \"%s\"\n", *argv);
  1035.     return 1;
  1036.       }
  1037.     }
  1038.   for (i = 0, j = hdr.nextdigi - 1; i < j; i++, j--) {
  1039.     addrcp(tmp, hdr.digis[i]);
  1040.     addrcp(hdr.digis[i], hdr.digis[j]);
  1041.     addrcp(hdr.digis[j], tmp);
  1042.   }
  1043.  
  1044.   axroute_add(iface, &hdr, perm);
  1045.   return 0;
  1046. }
  1047.  
  1048. /*---------------------------------------------------------------------------*/
  1049.  
  1050. static void doroutelistentry(rp)
  1051. struct ax_route *rp;
  1052. {
  1053.  
  1054.   char  *cp, buf[1024];
  1055.   int  i, n;
  1056.   int  perm;
  1057.   struct ax_route *rp_stack[20];
  1058.   struct iface *ifp;
  1059.   struct tm *tm;
  1060.  
  1061.   tm = gmtime(&rp->time);
  1062.   pax25(cp = buf, rp->call);
  1063.   perm = rp->perm;
  1064.   for (n = 0; rp; rp = rp->digi) {
  1065.     rp_stack[++n] = rp;
  1066.     ifp = rp->ifp;
  1067.   }
  1068.   for (i = n; i > 1; i--) {
  1069.     strcat(cp, i == n ? " via " : ",");
  1070.     while (*cp) cp++;
  1071.     pax25(cp, rp_stack[i]->call);
  1072.   }
  1073.   printf("%2d-%.3s  %-9s  %c %s\n",
  1074.      tm->tm_mday,
  1075.      "JanFebMarAprMayJunJulAugSepOctNovDec" + 3 * tm->tm_mon,
  1076.      ifp ? ifp->name : "???",
  1077.      perm ? '*' : ' ',
  1078.      buf);
  1079. }
  1080.  
  1081. /*---------------------------------------------------------------------------*/
  1082.  
  1083. static int  doroutelist(argc, argv, p)
  1084. int  argc;
  1085. char  *argv[];
  1086. void *p;
  1087. {
  1088.  
  1089.   char  call[AXALEN];
  1090.   int  i;
  1091.   struct ax_route *rp;
  1092.  
  1093.   puts("Date    Interface  P Path");
  1094.   if (argc < 2) {
  1095.     for (i = 0; i < AXROUTESIZE; i++)
  1096.       for (rp = Ax_routes[i]; rp; rp = rp->next) doroutelistentry(rp);
  1097.     return 0;
  1098.   }
  1099.   argc--;
  1100.   argv++;
  1101.   for (; argc > 0; argc--, argv++)
  1102.     if (setcall(call, *argv) || !(rp = ax_routeptr(call, 0)))
  1103.       printf("*** Not in table *** %s\n", *argv);
  1104.     else
  1105.       doroutelistentry(rp);
  1106.   return 0;
  1107. }
  1108.  
  1109. /*---------------------------------------------------------------------------*/
  1110.  
  1111. static int doroutestat(argc, argv, p)
  1112. int argc;
  1113. char *argv[];
  1114. void *p;
  1115. {
  1116.  
  1117. #define NIFACES 128
  1118.  
  1119.   struct ifptable_t {
  1120.     struct iface *ifp;
  1121.     int count;
  1122.   };
  1123.  
  1124.   int dev;
  1125.   int i;
  1126.   int total;
  1127.   struct ax_route *dp;
  1128.   struct ax_route *rp;
  1129.   struct iface *ifp;
  1130.   struct ifptable_t ifptable[NIFACES];
  1131.  
  1132.   memset(ifptable, 0, sizeof(ifptable));
  1133.   for (dev = 0, ifp = Ifaces; ifp; dev++, ifp = ifp->next)
  1134.     ifptable[dev].ifp = ifp;
  1135.   for (i = 0; i < AXROUTESIZE; i++)
  1136.     for (rp = Ax_routes[i]; rp; rp = rp->next) {
  1137.       for (dp = rp; dp->digi; dp = dp->digi) ;
  1138.       if (dp->ifp)
  1139.     for (dev = 0; dev < NIFACES; dev++)
  1140.       if (ifptable[dev].ifp == dp->ifp) {
  1141.         ifptable[dev].count++;
  1142.         break;
  1143.       }
  1144.     }
  1145.   puts("Interface  Count");
  1146.   total = 0;
  1147.   for (dev = 0; dev < NIFACES; dev++) {
  1148.     if (ifptable[dev].count || ifptable[dev].ifp == axroute_default_ifp)
  1149.       printf("%c %-7s  %5d\n",
  1150.          ifptable[dev].ifp == axroute_default_ifp ? '*' : ' ',
  1151.          ifptable[dev].ifp->name,
  1152.          ifptable[dev].count);
  1153.     total += ifptable[dev].count;
  1154.   }
  1155.   puts("---------  -----");
  1156.   printf("  total    %5d\n", total);
  1157.   return 0;
  1158. }
  1159.  
  1160. /*---------------------------------------------------------------------------*/
  1161.  
  1162. static int  doaxroute(argc, argv, p)
  1163. int  argc;
  1164. char  *argv[];
  1165. void *p;
  1166. {
  1167.  
  1168.   static struct cmds routecmds[] = {
  1169.  
  1170.     "add",  dorouteadd,  0, 3, "ax25 route add [permanent] <interface> default|<path>",
  1171.     "list", doroutelist, 0, 0, NULLCHAR,
  1172.     "stat", doroutestat, 0, 0, NULLCHAR,
  1173.  
  1174.     NULLCHAR, NULLFP,    0, 0, NULLCHAR
  1175.   };
  1176.  
  1177.   axroute_loadfile();
  1178.   if (argc >= 2) return subcmd(routecmds, argc, argv, p);
  1179.   doroutestat(argc, argv, p);
  1180.   return 0;
  1181. }
  1182.  
  1183. /*---------------------------------------------------------------------------*/
  1184.  
  1185. /* Display AX.25 link level control blocks */
  1186.  
  1187. static int  doaxstatus(argc, argv, p)
  1188. int  argc;
  1189. char  *argv[];
  1190. void *p;
  1191. {
  1192.  
  1193.   int  i;
  1194.   struct ax25_cb *cp;
  1195.   struct mbuf *bp;
  1196.  
  1197.   if (argc < 2) {
  1198.     printf("   &AXCB Rcv-Q Unack  Rt  Srtt  State          Remote socket\n");
  1199.     for (cp = axcb_head; cp; cp = cp->next)
  1200.       printf("%8lx %5u%c%3u/%u%c %2d%6lu  %-13s  %s\n",
  1201.          (long) cp,
  1202.          cp->rcvcnt,
  1203.          cp->rnrsent ? '*' : ' ',
  1204.          cp->unack,
  1205.          cp->cwind,
  1206.          cp->remote_busy ? '*' : ' ',
  1207.          cp->retry,
  1208.          cp->srtt,
  1209.          ax25states[cp->state],
  1210.          ax25hdr_to_string(&cp->hdr));
  1211.     if (axcb_server)
  1212.       printf("%8lx                        Listen (S)     *\n",
  1213.          (long) axcb_server);
  1214.   } else {
  1215.     cp = (struct ax25_cb *) htol(argv[1]);
  1216.     if (!valid_ax(cp)) {
  1217.       printf("Not a valid control block address\n");
  1218.       return 1;
  1219.     }
  1220.     printf("Path:         %s\n", ax25hdr_to_string(&cp->hdr));
  1221.     printf("Interface:    %s\n", cp->ifp ? cp->ifp->name : "---");
  1222.     printf("State:        %s\n", (cp == axcb_server) ? "Listen (S)" : ax25states[cp->state]);
  1223.     if (cp->reason)
  1224.       printf("Reason:       %s\n", ax25reasons[cp->reason]);
  1225.     printf("Mode:         %s\n", (cp->mode == STREAM) ? "Stream" : "Dgram");
  1226.     printf("Closed:       %s\n", cp->closed ? "Yes" : "No");
  1227.     printf("Polling:      %s\n", cp->polling ? "Yes" : "No");
  1228.     printf("RNRsent:      %s\n", cp->rnrsent ? "Yes" : "No");
  1229.     printf("REJsent:      %s\n", cp->rejsent ? "Yes" : "No");
  1230.     if (cp->remote_busy)
  1231.       printf("Remote_busy:  %lu ms\n", msclock() - cp->remote_busy);
  1232.     else
  1233.       printf("Remote_busy:  No\n");
  1234.     printf("CWind:        %d\n", cp->cwind);
  1235.     printf("Retry:        %d\n", cp->retry);
  1236.     printf("Srtt:         %ld ms\n", cp->srtt);
  1237.     printf("Mean dev:     %ld ms\n", cp->mdev);
  1238.     printf("Timer T1:     ");
  1239.     if (run_timer(&cp->timer_t1))
  1240.       printf("%lu", read_timer(&cp->timer_t1));
  1241.     else
  1242.       printf("stop");
  1243.     printf("/%lu ms\n", dur_timer(&cp->timer_t1));
  1244.     printf("Timer T2:     ");
  1245.     if (run_timer(&cp->timer_t2))
  1246.       printf("%lu", read_timer(&cp->timer_t2));
  1247.     else
  1248.       printf("stop");
  1249.     printf("/%lu ms\n", dur_timer(&cp->timer_t2));
  1250.     printf("Timer T3:     ");
  1251.     if (run_timer(&cp->timer_t3))
  1252.       printf("%lu", read_timer(&cp->timer_t3));
  1253.     else
  1254.       printf("stop");
  1255.     printf("/%lu ms\n", dur_timer(&cp->timer_t3));
  1256.     printf("Timer T4:     ");
  1257.     if (run_timer(&cp->timer_t4))
  1258.       printf("%lu", read_timer(&cp->timer_t4));
  1259.     else
  1260.       printf("stop");
  1261.     printf("/%lu ms\n", dur_timer(&cp->timer_t4));
  1262.     printf("Timer T5:     ");
  1263.     if (run_timer(&cp->timer_t5))
  1264.       printf("%lu", read_timer(&cp->timer_t5));
  1265.     else
  1266.       printf("stop");
  1267.     printf("/%lu ms\n", dur_timer(&cp->timer_t5));
  1268.     printf("Rcv queue:    %d\n", cp->rcvcnt);
  1269.     if (cp->reseq[0].bp || cp->reseq[1].bp ||
  1270.     cp->reseq[2].bp || cp->reseq[3].bp ||
  1271.     cp->reseq[4].bp || cp->reseq[5].bp ||
  1272.     cp->reseq[6].bp || cp->reseq[7].bp) {
  1273.       printf("Reassembly queue:\n");
  1274.       for (i = next_seq(cp->vr); i != cp->vr; i = next_seq(i))
  1275.     if (cp->reseq[i].bp)
  1276.       printf("              Seq %3d: %3d bytes\n",
  1277.          i, len_p(cp->reseq[i].bp));
  1278.     }
  1279.     printf("Snd queue:    %d\n", len_p(cp->sndq));
  1280.     if (cp->resndq) {
  1281.       printf("Resend queue:\n");
  1282.       for (i = 0, bp = cp->resndq; bp; i++, bp = bp->anext)
  1283.     printf("              Seq %3d: %3d bytes\n",
  1284.            (cp->vs - cp->unack + i) & 7, len_p(bp));
  1285.     }
  1286.   }
  1287.   return 0;
  1288. }
  1289.  
  1290. /*---------------------------------------------------------------------------*/
  1291.  
  1292. /* Set retransmission timer */
  1293.  
  1294. static int  dot1(argc, argv, p)
  1295. int  argc;
  1296. char  *argv[];
  1297. void *p;
  1298. {
  1299.   return setintrc(&ax_t1init, "T1 (ms)", argc, argv, 1, 0x7fffffff);
  1300. }
  1301.  
  1302. /*---------------------------------------------------------------------------*/
  1303.  
  1304. /* Set acknowledgement delay timer */
  1305.  
  1306. static int  dot2(argc, argv, p)
  1307. int  argc;
  1308. char  *argv[];
  1309. void *p;
  1310. {
  1311.   return setintrc(&ax_t2init, "T2 (ms)", argc, argv, 1, 0x7fffffff);
  1312. }
  1313.  
  1314. /*---------------------------------------------------------------------------*/
  1315.  
  1316. /* Set no-activity timer */
  1317.  
  1318. static int  dot3(argc, argv, p)
  1319. int  argc;
  1320. char  *argv[];
  1321. void *p;
  1322. {
  1323.   return setintrc(&ax_t3init, "T3 (ms)", argc, argv, 0, 0x7fffffff);
  1324. }
  1325.  
  1326. /*---------------------------------------------------------------------------*/
  1327.  
  1328. /* Set busy timer */
  1329.  
  1330. static int  dot4(argc, argv, p)
  1331. int  argc;
  1332. char  *argv[];
  1333. void *p;
  1334. {
  1335.   return setintrc(&ax_t4init, "T4 (ms)", argc, argv, 1, 0x7fffffff);
  1336. }
  1337.  
  1338. /*---------------------------------------------------------------------------*/
  1339.  
  1340. /* Set packet assembly timer */
  1341.  
  1342. static int  dot5(argc, argv, p)
  1343. int  argc;
  1344. char  *argv[];
  1345. void *p;
  1346. {
  1347.   return setintrc(&ax_t5init, "T5 (ms)", argc, argv, 1, 0x7fffffff);
  1348. }
  1349.  
  1350. /*---------------------------------------------------------------------------*/
  1351.  
  1352. /* Set high water mark on receive queue that triggers RNR */
  1353.  
  1354. static int  doaxwindow(argc, argv, p)
  1355. int  argc;
  1356. char  *argv[];
  1357. void *p;
  1358. {
  1359.   return setintrc(&ax_window, "Window", argc, argv, 1, MAXINT16);
  1360. }
  1361.  
  1362. /*---------------------------------------------------------------------------*/
  1363.  
  1364. /* Multiplexer for top-level ax25 command */
  1365.  
  1366. int  doax25(argc, argv, p)
  1367. int  argc;
  1368. char  *argv[];
  1369. void *p;
  1370. {
  1371.  
  1372.   static struct cmds axcmds[] = {
  1373.  
  1374.     "digipeat", dodigipeat, 0, 0, NULLCHAR,
  1375.     "kick",     doaxkick,   0, 2, "ax25 kick <axcb>",
  1376.     "maxframe", domaxframe, 0, 0, NULLCHAR,
  1377.     "mycall",   domycall,   0, 0, NULLCHAR,
  1378.     "paclen",   dopaclen,   0, 0, NULLCHAR,
  1379.     "pthresh",  dopthresh,  0, 0, NULLCHAR,
  1380.     "reset",    doaxreset,  0, 2, "ax25 reset <axcb>",
  1381.     "retry",    doretry,    0, 0, NULLCHAR,
  1382.     "route",    doaxroute,  0, 0, NULLCHAR,
  1383.     "status",   doaxstatus, 0, 0, NULLCHAR,
  1384.     "t1",       dot1,       0, 0, NULLCHAR,
  1385.     "t2",       dot2,       0, 0, NULLCHAR,
  1386.     "t3",       dot3,       0, 0, NULLCHAR,
  1387.     "t4",       dot4,       0, 0, NULLCHAR,
  1388.     "t5",       dot5,       0, 0, NULLCHAR,
  1389.     "window",   doaxwindow, 0, 0, NULLCHAR,
  1390.  
  1391.     NULLCHAR,   NULLFP,     0, 0, NULLCHAR
  1392.   };
  1393.  
  1394.   return subcmd(axcmds, argc, argv, p);
  1395. }
  1396.  
  1397. /*---------------------------------------------------------------------------*/
  1398. /***************************** User Calls to AX25 ****************************/
  1399. /*---------------------------------------------------------------------------*/
  1400.  
  1401. struct ax25_cb *open_ax(path, mode, r_upcall, t_upcall, s_upcall, user)
  1402. char  *path;
  1403. int  mode;
  1404. void (*r_upcall) __ARGS((struct ax25_cb *p, int cnt));
  1405. void (*t_upcall) __ARGS((struct ax25_cb *p, int cnt));
  1406. void (*s_upcall) __ARGS((struct ax25_cb *p, int oldstate, int newstate));
  1407. char  *user;
  1408. {
  1409.  
  1410.   char  *ap;
  1411.   struct ax25 hdr;
  1412.   struct ax25_cb *cp;
  1413.  
  1414.   switch (mode) {
  1415.   case AX_ACTIVE:
  1416.     hdr.ndigis = hdr.nextdigi = 0;
  1417.     ap = path;
  1418.     addrcp(hdr.dest, ap);
  1419.     ap += AXALEN;
  1420.     addrcp(hdr.source, ap);
  1421.     ap += AXALEN;
  1422.     while (!(ap[-1] & E)) {
  1423.       addrcp(hdr.digis[hdr.ndigis++], ap);
  1424.       ap += AXALEN;
  1425.     }
  1426.     for (cp = axcb_head; cp; cp = cp->next)
  1427.       if (!cp->peer && addreq(hdr.dest, cp->hdr.dest)) {
  1428.     Net_error = CON_EXISTS;
  1429.     return NULLAXCB;
  1430.       }
  1431.     if (!(cp = create_axcb(NULLAXCB))) {
  1432.       Net_error = NO_MEM;
  1433.       return NULLAXCB;
  1434.     }
  1435.     build_path(cp, NULLIF, &hdr, 0);
  1436.     cp->r_upcall = r_upcall;
  1437.     cp->t_upcall = t_upcall;
  1438.     cp->s_upcall = s_upcall;
  1439.     cp->user = user;
  1440.     setaxstate(cp, CONNECTING);
  1441.     return cp;
  1442.   case AX_SERVER:
  1443.     if (!(cp = (struct ax25_cb *) calloc(1, sizeof(struct ax25_cb )))) {
  1444.       Net_error = NO_MEM;
  1445.       return NULLAXCB;
  1446.     }
  1447.     cp->r_upcall = r_upcall;
  1448.     cp->t_upcall = t_upcall;
  1449.     cp->s_upcall = s_upcall;
  1450.     cp->user = user;
  1451.     return cp;
  1452.   default:
  1453.     Net_error = INVALID;
  1454.     return NULLAXCB;
  1455.   }
  1456. }
  1457.  
  1458. /*---------------------------------------------------------------------------*/
  1459.  
  1460. int  send_ax(cp, bp)
  1461. struct ax25_cb *cp;
  1462. struct mbuf *bp;
  1463. {
  1464.   int cnt;
  1465.  
  1466.   if (!(cp && bp)) {
  1467.     free_p(bp);
  1468.     Net_error = INVALID;
  1469.     return (-1);
  1470.   }
  1471.   switch (cp->state) {
  1472.   case DISCONNECTED:
  1473.     free_p(bp);
  1474.     Net_error = NO_CONN;
  1475.     return (-1);
  1476.   case CONNECTING:
  1477.   case CONNECTED:
  1478.     if (!cp->closed) {
  1479.       if (cnt = len_p(bp)) {
  1480.     if (cp->mode == STREAM)
  1481.       append(&cp->sndq, bp);
  1482.     else
  1483.       enqueue(&cp->sndq, bp);
  1484.     cp->sndqtime = msclock();
  1485.     try_send(cp, 0);
  1486.       }
  1487.       return cnt;
  1488.     }
  1489.   case DISCONNECTING:
  1490.     free_p(bp);
  1491.     Net_error = CON_CLOS;
  1492.     return (-1);
  1493.   }
  1494.   return (-1);
  1495. }
  1496.  
  1497. /*---------------------------------------------------------------------------*/
  1498.  
  1499. int  space_ax(cp)
  1500. struct ax25_cb *cp;
  1501. {
  1502.   int  cnt;
  1503.  
  1504.   if (!cp) {
  1505.     Net_error = INVALID;
  1506.     return (-1);
  1507.   }
  1508.   switch (cp->state) {
  1509.   case DISCONNECTED:
  1510.     Net_error = NO_CONN;
  1511.     return (-1);
  1512.   case CONNECTING:
  1513.   case CONNECTED:
  1514.     if (!cp->closed) {
  1515.       cnt = (cp->cwind - cp->unack) * ax_paclen - len_p(cp->sndq);
  1516.       return (cnt > 0) ? cnt : 0;
  1517.     }
  1518.   case DISCONNECTING:
  1519.     Net_error = CON_CLOS;
  1520.     return (-1);
  1521.   }
  1522.   return (-1);
  1523. }
  1524.  
  1525. /*---------------------------------------------------------------------------*/
  1526.  
  1527. int  recv_ax(cp, bpp, cnt)
  1528. struct ax25_cb *cp;
  1529. struct mbuf **bpp;
  1530. int cnt;
  1531. {
  1532.   if (!(cp && bpp)) {
  1533.     Net_error = INVALID;
  1534.     return (-1);
  1535.   }
  1536.   if (cp->rcvcnt) {
  1537.     if (cp->mode == DGRAM || !cnt || cp->rcvcnt <= cnt) {
  1538.       *bpp = dequeue(&cp->rcvq);
  1539.       cnt = len_p(*bpp);
  1540.     } else {
  1541.       if (!(*bpp = alloc_mbuf(cnt))) {
  1542.     Net_error = NO_MEM;
  1543.     return (-1);
  1544.       }
  1545.       pullup(&cp->rcvq, (*bpp)->data, cnt);
  1546.       (*bpp)->cnt = cnt;
  1547.     }
  1548.     cp->rcvcnt -= cnt;
  1549.     if (cp->rnrsent && !busy(cp)) send_ack(cp, RESP);
  1550.     return cnt;
  1551.   }
  1552.   switch (cp->state) {
  1553.   case CONNECTING:
  1554.   case CONNECTED:
  1555.     *bpp = NULLBUF;
  1556.     Net_error = WOULDBLK;
  1557.     return (-1);
  1558.   case DISCONNECTED:
  1559.   case DISCONNECTING:
  1560.     *bpp = NULLBUF;
  1561.     return 0;
  1562.   }
  1563.   return (-1);
  1564. }
  1565.  
  1566. /*---------------------------------------------------------------------------*/
  1567.  
  1568. int  close_ax(cp)
  1569. struct ax25_cb *cp;
  1570. {
  1571.   if (!cp) {
  1572.     Net_error = INVALID;
  1573.     return (-1);
  1574.   }
  1575.   if (cp->closed) {
  1576.     Net_error = CON_CLOS;
  1577.     return (-1);
  1578.   }
  1579.   cp->closed = 1;
  1580.   switch (cp->state) {
  1581.   case DISCONNECTED:
  1582.     Net_error = NO_CONN;
  1583.     return (-1);
  1584.   case CONNECTING:
  1585.     setaxstate(cp, DISCONNECTED);
  1586.     return 0;
  1587.   case CONNECTED:
  1588.     if (!cp->sndq && !cp->unack) setaxstate(cp, DISCONNECTING);
  1589.     return 0;
  1590.   case DISCONNECTING:
  1591.     Net_error = CON_CLOS;
  1592.     return (-1);
  1593.   }
  1594.   return (-1);
  1595. }
  1596.  
  1597. /*---------------------------------------------------------------------------*/
  1598.  
  1599. int  reset_ax(cp)
  1600. struct ax25_cb *cp;
  1601. {
  1602.   if (!cp) {
  1603.     Net_error = INVALID;
  1604.     return (-1);
  1605.   }
  1606.   if (cp == axcb_server) {
  1607.     free(axcb_server);
  1608.     axcb_server = NULLAXCB;
  1609.     return 0;
  1610.   }
  1611.   cp->reason = RESET;
  1612.   setaxstate(cp, DISCONNECTED);
  1613.   return 0;
  1614. }
  1615.  
  1616. /*---------------------------------------------------------------------------*/
  1617.  
  1618. int  del_ax(cp)
  1619. struct ax25_cb *cp;
  1620. {
  1621.  
  1622.   int  i;
  1623.   struct ax25_cb *p, *q;
  1624.  
  1625.   for (q = 0, p = axcb_head; p != cp; q = p, p = p->next)
  1626.     if (!p) {
  1627.       Net_error = INVALID;
  1628.       return (-1);
  1629.     }
  1630.   if (q)
  1631.     q->next = p->next;
  1632.   else
  1633.     axcb_head = p->next;
  1634.   stop_timer(&cp->timer_t1);
  1635.   stop_timer(&cp->timer_t2);
  1636.   stop_timer(&cp->timer_t3);
  1637.   stop_timer(&cp->timer_t4);
  1638.   stop_timer(&cp->timer_t5);
  1639.   for (i = 0; i < 8; i++) free_p(cp->reseq[i].bp);
  1640.   free_q(&cp->rcvq);
  1641.   free_q(&cp->sndq);
  1642.   free_q(&cp->resndq);
  1643.   free(cp);
  1644.   return 0;
  1645. }
  1646.  
  1647. /*---------------------------------------------------------------------------*/
  1648.  
  1649. int  valid_ax(cp)
  1650. struct ax25_cb *cp;
  1651. {
  1652.   struct ax25_cb *p;
  1653.  
  1654.   if (!cp) return 0;
  1655.   if (cp == axcb_server) return 1;
  1656.   for (p = axcb_head; p; p = p->next)
  1657.     if (p == cp) return 1;
  1658.   return 0;
  1659. }
  1660.  
  1661. /*---------------------------------------------------------------------------*/
  1662.  
  1663. /* Force a retransmission */
  1664.  
  1665. int  kick_ax(axp)
  1666. struct ax25_cb *axp;
  1667. {
  1668.   if (!valid_ax(axp)) return -1;
  1669.   t1_timeout(axp);
  1670.   return 0;
  1671. }
  1672.  
  1673.